namespace :init do
  # rake init:stock
  desc "stock"
  task stock: :environment do
    puts "【init:stock】start_time: #{Time.now}"
    stock_basic = $TusharePro.tushare_pro "stock_basic", "market" => "主板,创业板"

    symbols_to_delete = Stock.where(symbol: Stock.all.pluck(:symbol) - stock_basic.pluck("symbol"))
    BlockStock.where(stock_id: symbols_to_delete.pluck(:id)).delete_all
    symbols_to_delete.delete_all

    Parallel.map(stock_basic, in_processes: 1, progress: true) do |stock_basic|
      stock = Stock.find_or_initialize_by(symbol: stock_basic["symbol"])
      stock.update(stock_basic)
    end

    stock_basic.each_slice(300).each do |batch|
      lls = $TusharePro.tushare_pro("limit_list_d", "ts_code": batch.pluck("ts_code").join(','), "limit_type": "U", "start_date": (Time.now - 365.day).strftime("%Y%m%d"), "end_date": Time.now.strftime("%Y%m%d"))
      puts lls.count
      lls.group_by { |x| x["ts_code"] }.each do |ts_code, limits|
        puts ts_code if Stock.find_by_symbol(ts_code[0..5]).nil?
        Stock.find_by_symbol(ts_code[0..5]).update_attribute("year_count", limits.count)
      end
    end

    Stock.all.update_all(ths_flow: nil)
    Stock.all.update_all(score: nil)

    Stock.where(is_industry: true).update_all(is_industry: false)
    $TusharePro.tushare_pro("ths_index", exchange: "A", type: "I").select { |x| x["ts_code"][0] == "8" && x["count"] != nil }.each do |ths_index|
      members = $TusharePro.tushare_pro("ths_member", "ts_code": ths_index["ts_code"]).select { |x| x["con_code"][0..5] < "680000" && x["con_code"][0] != "4" }
      delay_millisecond(1, 58) do
        stock = Stock.find_by_ts_code(members.first["con_code"])
        stock.update(is_industry: true) if stock
      end
    end
    Robot.send_init "**INIT STOCK**"
    puts "【init:stock】end_time: #{Time.now}"
  end
  # rake init:block
  desc "block"
  task block: :environment do
    # "I" => 行业(281)， "N" => 板块(402)， "S" => 同花顺特色(108)
    puts "【init:block】start_time: #{Time.now}"
    ths_indexs_I = $TusharePro.tushare_pro("ths_index", exchange: "A", type: "I").select { |x| x["ts_code"][0] == "8" }
    ths_indexs_I.each do |ths_index|
      stock_ths_block = Block.find_by_ts_code ths_index["ts_code"]
      if stock_ths_block
        stock_ths_block.update(name: ths_index["name"], count: ths_index["count"], cate_type: ths_index["type"])
      else
        Block.create(ts_code: ths_index["ts_code"], name: ths_index["name"], count: ths_index["count"], cate_type: ths_index["type"])
        Robot.send_alert "**INIT BLOCK** NEW #{ths_index["name"]}-#{ths_index["ts_code"]}"
      end
      members = $TusharePro.tushare_pro("ths_member", "ts_code": ths_index["ts_code"]).select { |x| x["con_code"][0..5] < "680000" && x["con_code"][0] != "4" }
      member_ids = members.pluck("con_code")

      block = Block.find_by_ts_code ths_index["ts_code"]
      block_stock_ids = block.stocks.pluck(:ts_code)

      ts_codes = member_ids - block_stock_ids
      if ts_codes.empty?
        delay_millisecond(1, 288){}
      end
      ts_codes.each do |ts_code|
        stock = Stock.find_by_ts_code(ts_code)
        next if stock.nil?
        block.block_stocks.create stock_id: stock.id
      end
    end
    ths_indexs_N = $TusharePro.tushare_pro("ths_index", exchange: "A", type: "N")
    ths_indexs_N.each do |ths_index|
      stock_ths_block = Block.find_by_ts_code ths_index["ts_code"]
      if stock_ths_block
        stock_ths_block.update(name: ths_index["name"], count: ths_index["count"], cate_type: ths_index["type"])
      else
        Block.create(ts_code: ths_index["ts_code"], name: ths_index["name"], count: ths_index["count"], cate_type: ths_index["type"])
        Robot.send_alert "**INIT BLOCK** NEW #{ths_index["name"]}-#{ths_index["ts_code"]}"
      end
      members = $TusharePro.tushare_pro("ths_member", "ts_code": ths_index["ts_code"]).select { |x| x["con_code"][0..5] < "680000" && x["con_code"][0] != "4" }
      member_ids = members.pluck("con_code")

      block = Block.find_by_ts_code ths_index["ts_code"]
      block_stock_ids = block.stocks.pluck(:ts_code)

      ts_codes = member_ids - block_stock_ids
      delay_millisecond(1, 288){} if ts_codes.empty?
      ts_codes.each do |ts_code|
        stock = Stock.find_by_ts_code(ts_code)
        next if stock.nil?
        block.block_stocks.create stock_id: stock.id
      end
    end
    Robot.send_init "**INIT BLOCK**"
    puts "【init:block】end_time: #{Time.now}"
  end

  # rake init:limit_list   # TODO 写清楚执行策略，每天？？执行一次？
  desc "每日导入涨停板数据"
  task limit_list: :environment do
    puts "【init:limit_list】#{Time.now}  start"
    (puts "非交易日不执行"; abort) if Time.now.strftime("%Y%m%d") != last_trade_date["cal_date"]
    limit_list_ds = limit_list_d(last_trade_date["cal_date"]).select { |x| %w(3 6 0).include?(x["ts_code"][0]) && x["ts_code"][0..2] != "688" }
    limit_list_ds = limit_list_d(last_trade_date["pretrade_date"]).select { |x| %w(3 6 0).include?(x["ts_code"][0]) && x["ts_code"][0..2] != "688" } if limit_list_ds.empty?
    (puts "涨停数据已经初始化，不重复执行"; abort) if LimitList.last.trade_date.strftime("%Y%m%d") == limit_list_ds.last["trade_date"]

    limit_list_ds.each_slice(20).each do |batch|
      lls = $TusharePro.tushare_pro("limit_list_d", "ts_code": batch.pluck("ts_code").join(','), "limit_type": "U", "start_date": (Time.now - 365.day).strftime("%Y%m%d"), "end_date": Time.now.strftime("%Y%m%d"))
      lls.group_by { |x| x["ts_code"] }.each do |ts_code, limits|
        limit = limit_list_ds.select { |x| x["ts_code"] == ts_code }.first
        limit["year_count"] = limits.count
        fluctuation = Fluctuation.where(code: ts_code[0..5]).where(trend: ['大涨', '涨停']).first
        if fluctuation.nil?
          limit["reason"] = nil
        else
          limit["reason"] = fluctuation.title.split('：')[1]
        end
        LimitList.create(limit)
      end
    end
    Robot.send_init "**INIT limit_list**"
    puts "【init:limit_list】#{Time.now}  end"
  end

  # rake init:buy_point
  desc "buy_point"
  task buy_point: :environment do
    puts "【init:buy_point】#{Time.now}  start"
    (puts "非交易日不执行"; abort) if Time.now.strftime("%Y%m%d") != last_trade_date["cal_date"]
    Stock.all.each do |stock|
      RealTime.buy_sell_point(to_sina_code(stock.symbol))[Time.now.strftime("%Y-%m-%d")] == "1" ? stock.update(is_buy_point: true) : stock.update(is_buy_point: false)
    end
    Robot.send_init "**INIT BUY_POINT**"
    puts "【init:buy_point】#{Time.now}  end"
  end
end